package com.ericsson.common.util;

import java.io.*;
import java.net.SocketException;

import org.apache.commons.net.telnet.TelnetClient;
public class TelnetUtils {
    private TelnetClient telnet = null;

    private String prompt = "#$>]";
    private String loginPrompt = "login";

    private String usernamePrompt = "Username:";
    private String passwordPrompt = "Password:";


    private InputStream in;
    private PrintStream out;

    public TelnetUtils(String host, int port) {
        if(telnet == null) {
            telnet = new TelnetClient();
            try {
                telnet.connect(host, port);
                in = telnet.getInputStream();
                out = new PrintStream(telnet.getOutputStream());
            } catch (SocketException e) {
            } catch (IOException e) {
            }
        }
    }

    /**
     * 登录到远程机器中<br>
     * 说明：在登录前，先确认输入用户名的提示符，如果不是Username：，需要设置该值，使用setUsernamePrompt(prompt)；<br>
     *       第二，确认输入密码时的提示符，如果不是Password：，需要设置该值,使用setPasswordPrompt(prompt)；<br>
     *       第三，确认登录后查看是否有登录后的提示信息：如：%Apr 17 04:26:32:256 2000 Quidway SHELL/5/LOGIN:- 1 - admin(191.168.2.227) in unit1 login <br>
     *             如果末尾不是login,需要指定最后一个单词，使用setLoginPrompt(prompt).
     *             如果没有登录提示，设置setLoginPrompt(null);
     *       第四，执行命令时，如果提示符不是 #、$、>、]中的一个，也需要指定最后一个符号，使用setPrompt(prompt).
     */
    public void login(String username, String password, String prompt) {
        loginForWin(username, password, prompt);
    }
    public String loginForWin(String username, String password, String prompt) {
        //处理命令行的提示字符
        if(prompt != null && !"".equals(prompt)) {
            this.prompt = prompt;
        }
        String result = "";
        readUntil(this.usernamePrompt);
        write(username);
        readUntil(this.passwordPrompt);
        write(password);
        result = readUntil(this.prompt);
        if(this.loginPrompt != null)
            result += readUntil(this.loginPrompt);
        return result;
    }


    /** * 读取分析结果 * * @param pattern * @return */
    private String readUntil(String pattern) {
        StringBuffer sb = new StringBuffer();

        try {
            int len = 0;
            while((len = in.read()) != -1) {
                char ch = (char)len;
                sb.append(ch);
                if(sb.toString().indexOf(pattern) != -1 || sb.toString().endsWith(pattern)) {
                    return sb.toString();
                }
            }
        } catch (IOException e) {
        }

        return "";
    }

    public static void main(String[] args) {
        System.out.println("#".charAt(0));
    }
    /** * 读取分析结果 * * @param pattern * @return * count 判断第几次出现 pattern 有效 */
    private String readUntil(String pattern,int count) {
        StringBuffer sb = new StringBuffer();
        char p=pattern.charAt(0);
        try {
            int len = 0;
            while((len = in.read()) != -1) {
                char ch = (char)len;
                sb.append(ch);
                if(p==ch) {
                    if(count<=1) {
                        return sb.toString();
                    }else{
                        count=count-1;
                    }
                }
            }
        } catch (IOException e) {
        }

        return "";
    }
    /**
     * tab提示  命令补全
     * @return
     */
    private String readUntil() {
        StringBuffer sb = new StringBuffer();
        boolean flag = false;
        try {
            int len = 0;
            int i = 0;
            Thread.sleep(500);
            int count = in.available();
            while((len = in.read()) != -1) {
                i++;
                char ch = (char)len;
                sb.append(ch);
                if(prompt.indexOf(ch) != -1) {
                    flag = true;
                }
                if(flag && i == count) {
                    return sb.toString();
                }
            }
        } catch (IOException e) {
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(sb.toString());
        return sb.toString();
    }


    /** * 写操作 * * @param value */
    private void write(String value) {
        try {
            out.println(value);
            out.flush();
        } catch (Exception e) {
        }
    }
    /** * 写操作 * * @param value */
    private void writeTab(String value) {
        try {
//			out.println();
            out.print(value);
            out.flush();
        } catch (Exception e) {
        }
    }

    /** * 向目标发送命令字符串 * * @param command * @return */
    public String sendCommand(String command) {
        try {
            write(command);
            return readUntil(prompt + "");
        } catch (Exception e) {
        }
        return "";
    }

    /** * 向目标发送命令字符串 * * @param command * @return count 判断第几次出现 pattern 有效 */
    public String sendCommand(String command,int count ) {
        try {
            write(command);
            return readUntil(prompt + "",count);
        } catch (Exception e) {
        }
        return "";
    }

    /** * 向目标发送命令字符串 * * @param command * @return */
    public String sendCommand(String command, boolean prom) {
        if(prom && command.indexOf("\t") == -1)
            command += "\t";
        try {
            writeTab(command);
            return readUntil();
        } catch (Exception e) {
        }
        return "";
    }

    /** * 关闭连接 */
    public void disconnect() {
        try {
            telnet.disconnect();
        } catch (Exception e) {
        }
    }

    /**
     * @return the prompt
     */
    public String getPrompt() {
        return prompt;
    }

    /**
     * @param prompt the prompt to set
     */
    public void setPrompt(String prompt) {
        this.prompt = prompt;
    }

    /**
     * @return the usernamePrompt
     */
    public String getUsernamePrompt() {
        return usernamePrompt;
    }

    /**
     * @param usernamePrompt the usernamePrompt to set
     */
    public void setUsernamePrompt(String usernamePrompt) {
        this.usernamePrompt = usernamePrompt;
    }

    /**
     * @return the passwordPrompt
     */
    public String getPasswordPrompt() {
        return passwordPrompt;
    }

    /**
     * @param passwordPrompt the passwordPrompt to set
     */
    public void setPasswordPrompt(String passwordPrompt) {
        this.passwordPrompt = passwordPrompt;
    }

    /**
     * @return the loginPrompt
     */
    public String getLoginPrompt() {
        return loginPrompt;
    }

    /**
     * @param loginPrompt the loginPrompt to set
     */
    public void setLoginPrompt(String loginPrompt) {
        this.loginPrompt = loginPrompt;
    }

    /**
     * 关闭打开的连接
     * @param telnet
     */
    public void close(TelnetClient telnet) {
        if(telnet != null) {
            try {
                telnet.disconnect();
                telnet = null;
            } catch (IOException e) {
            }
        }

        if(this.telnet != null) {
            try {
                this.telnet.disconnect();
                this.telnet = null;
            } catch (IOException e) {
            }
        }
    }






    public void login51(String prompt) {
        loginForWin51(prompt);
    }
    public String loginForWin51(String prompt) {
        //处理命令行的提示字符
        if(prompt != null && !"".equals(prompt)) {
            this.prompt = prompt;
        }
        String result = "";
        result = readUntil(this.prompt);
        if(this.loginPrompt != null)
            result += readUntil(this.loginPrompt);
        return result;
    }


    public void login61(String password, String prompt) {
        loginForWin61(password, prompt);
    }
    public String loginForWin61(String password, String prompt) {
        //处理命令行的提示字符
        if(prompt != null && !"".equals(prompt)) {
            this.prompt = prompt;
        }
        String result = "";
        readUntil(this.passwordPrompt);
        write(password);
        result = readUntil(this.prompt);
        if(this.loginPrompt != null)
            result += readUntil(this.loginPrompt);
        return result;
    }

    public String sendCommandVlan(String commandVlan){
        try {
            write(commandVlan);
            return readVlanUtil(prompt);
        } catch (Exception e) {
        }
        return "";
    }
    private String readVlanUtil(String pattern){
        BufferedReaderENIP br = null;
        try
        {
            br = new BufferedReaderENIP(new InputStreamReader(in),pattern.toCharArray()[0]);
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null)
            {
                if(line.indexOf(pattern) != -1 || line.endsWith(pattern)) {
                    return sb.toString();
                }
                sb.append(line).append("\n");
            }
            return sb.toString();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (br != null)
            {
                try
                {
                    br.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
        return "";
    }
}
